import axios from 'axios';
import router from '@/router';

const baseURL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api';
const timeout = 10000;

// 创建 Axios 实例
const service = axios.create({
  baseURL,
  timeout
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 1. 设置通用请求头
    // 可以根据需要动态设置 Content-Type
    // 如果是 FormData，浏览器会自动设置正确的 Content-Type (包含 boundary)
    // if (config.data instanceof FormData) {
    //   // 通常不需要手动设置，但可以确保
    //   // delete config.headers['Content-Type']; // 让浏览器自动设置
    // } else if (config.data && typeof config.data === 'object') {
    //   config.headers['Content-Type'] = 'application/json';
    // }

    // 2. 添加认证 token
    const token = localStorage.getItem('access_token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    console.error('Request Error:', error);
    return Promise.reject(error);
  },
);

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    const { code, message, data } = response.data;

    if (code === 200 || code === '200') {
      console.log(message);
      // 成功，返回 data
      return data;
    } else {
      // 业务逻辑错误
      const errorMsg = message || '请求失败';
      console.error(`Business Error: ${errorMsg} (Code: ${code})`);
      return Promise.reject(new Error(errorMsg));
    }
  },
  (error) => {
    // 处理 HTTP 状态码错误和网络错误
    let errorMessage = '未知错误';
    if (error.response) {
      // 服务器返回了错误响应
      const status = error.response.status;
      const dataMsg = error.response.data?.message;

      switch (status) {
        case 400:
          errorMessage = dataMsg || '请求参数错误';
          break;
        case 401:
          errorMessage = '未授权，请重新登录';
          localStorage.removeItem('token');
          router.push('/401');
          break;
        case 403:
          errorMessage = '拒绝访问';
          break;
        case 404:
          errorMessage = '请求地址出错';
          break;
        case 500:
          errorMessage = '服务器内部错误';
          break;
        default:
          errorMessage = dataMsg || `请求失败: ${status}`;
      }
    } else if (error.request) {
      // 请求已发出，但未收到响应 (网络问题)
      errorMessage = '网络连接失败';
    } else {
      // 其他错误 (如设置请求时出错)
      errorMessage = error.message;
    }

    console.error('Response Error:', errorMessage, error);
    return Promise.reject(new Error(errorMessage));
  },
);

// 通用请求函数，支持所有 HTTP 方法
function request(config) {
  return service(config);
}

// 提供便捷方法，允许在调用时指定 headers
const http = {
  get(url, params = {}, config = {}) {
    return request({
      method: 'GET',
      url,
      params, // GET 请求参数通常放在 query string
      ...config,
    });
  },

  post(url, data = {}, config = {}) {
    return request({
      method: 'POST',
      url,
      data,
      ...config,
    });
  },

  put(url, data = {}, config = {}) {
    return request({
      method: 'PUT',
      url,
      data,
      ...config,
    });
  },

  delete(url, config = {}) {
    return request({
      method: 'DELETE',
      url,
      ...config,
    });
  },

  // 上传文件 (multipart/form-data)
  upload(url, formData, config = {}) {
    return request({
      method: 'POST',
      url,
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data',
        ...config.headers, // 允许覆盖
      },
      ...config,
    });
  },

  // 下载文件 (blob)
  download(url, params = {}, config = {}) {
    return request({
      method: 'GET',
      url,
      params,
      responseType: 'blob', // 关键：设置响应类型为 blob
      ...config,
    });
  },

  // 发送 JSON 数据 (显式设置 Content-Type)
  postJson(url, data = {}, config = {}) {
    return request({
      method: 'POST',
      url,
      data,
      headers: {
        'Content-Type': 'application/json',
        ...config.headers,
      },
      ...config,
    });
  },

  // 发送 URL 编码表单数据
  postForm(url, data = {}, config = {}) {
    // 手动将对象转换为 application/x-www-form-urlencoded 格式
    const searchParams = new URLSearchParams();
    for (const [key, value] of Object.entries(data)) {
      searchParams.append(key, value);
    }
    return request({
      method: 'POST',
      url,
      data: searchParams,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        ...config.headers,
      },
      ...config,
    });
  },
};

export default http;
